Index: src/wp-includes/canonical.php
===================================================================
--- src/wp-includes/canonical.php	(revision 45452)
+++ src/wp-includes/canonical.php	(working copy)
@@ -19,8 +19,8 @@
  *
  * Prevents redirection for feeds, trackbacks, searches, and
  * admin URLs. Does not redirect on non-pretty-permalink-supporting IIS 7+,
- * page/post previews, WP admin, Trackbacks, robots.txt, searches, or on POST
- * requests.
+ * page/post previews, WP admin, Trackbacks, robots.txt, favicon.ico, searches,
+ * or on POST requests.
  *
  * Will also attempt to find the correct link when a user enters a URL that does
  * not exist based on exact WordPress query. Will instead try to parse the URL
@@ -56,7 +56,7 @@
 		}
 	}
 
-	if ( is_trackback() || is_search() || is_admin() || is_preview() || is_robots() || ( $is_IIS && ! iis7_supports_permalinks() ) ) {
+	if ( is_trackback() || is_search() || is_admin() || is_preview() || is_robots() || is_favicon() || ( $is_IIS && ! iis7_supports_permalinks() ) ) {
 		return;
 	}
 
Index: src/wp-includes/class-wp-query.php
===================================================================
--- src/wp-includes/class-wp-query.php	(revision 45452)
+++ src/wp-includes/class-wp-query.php	(working copy)
@@ -391,6 +391,14 @@
 	public $is_robots = false;
 
 	/**
+	 * Signifies whether the current query is for the favicon.ico file.
+	 *
+	 * @since 5.3.0
+	 * @var bool
+	 */
+	public $is_favicon = false;
+
+	/**
 	 * Signifies whether the current query is for the page_for_posts page.
 	 *
 	 * Basically, the homepage if the option isn't set for the static homepage.
@@ -478,6 +486,7 @@
 		$this->is_attachment        = false;
 		$this->is_singular          = false;
 		$this->is_robots            = false;
+		$this->is_favicon           = false;
 		$this->is_posts_page        = false;
 		$this->is_post_type_archive = false;
 	}
@@ -742,6 +751,8 @@
 
 		if ( ! empty( $qv['robots'] ) ) {
 			$this->is_robots = true;
+		} elseif ( ! empty( $qv['favicon'] ) ) {
+			$this->is_favicon = true;
 		}
 
 		if ( ! is_scalar( $qv['p'] ) || $qv['p'] < 0 ) {
@@ -955,7 +966,9 @@
 			$this->is_comment_feed = true;
 		}
 
-		if ( ! ( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_robots ) ) {
+		if ( ! ( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed
+				|| ( defined( 'REST_REQUEST' ) && REST_REQUEST )
+				|| $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_robots || $this->is_favicon ) ) {
 			$this->is_home = true;
 		}
 
@@ -3998,7 +4011,7 @@
 	}
 
 	/**
-	 * Is the query for the robots file?
+	 * Is the query for the robots.txt file?
 	 *
 	 * @since 3.1.0
 	 *
@@ -4009,6 +4022,17 @@
 	}
 
 	/**
+	 * Is the query for the favicon.ico file?
+	 *
+	 * @since 5.3.0
+	 *
+	 * @return bool
+	 */
+	public function is_favicon() {
+		return (bool) $this->is_favicon;
+	}
+
+	/**
 	 * Is the query for a search?
 	 *
 	 * @since 3.1.0
Index: src/wp-includes/class-wp-rewrite.php
===================================================================
--- src/wp-includes/class-wp-rewrite.php	(revision 45452)
+++ src/wp-includes/class-wp-rewrite.php	(working copy)
@@ -1259,10 +1259,13 @@
 			return $rewrite;
 		}
 
-		// robots.txt -only if installed at the root
+		// robots.txt -- only if installed at the root
 		$home_path      = parse_url( home_url() );
 		$robots_rewrite = ( empty( $home_path['path'] ) || '/' == $home_path['path'] ) ? array( 'robots\.txt$' => $this->index . '?robots=1' ) : array();
 
+		// favicon.ico -- only if installed at the root
+		$favicon_rewrite = ( empty( $home_path['path'] ) || '/' == $home_path['path'] ) ? array( 'favicon\.ico$' => $this->index . '?favicon=1' ) : array();
+
 		// Old feed and service files.
 		$deprecated_files = array(
 			'.*wp-(atom|rdf|rss|rss2|feed|commentsrss2)\.php$' => $this->index . '?feed=old',
@@ -1419,9 +1422,9 @@
 
 		// Put them together.
 		if ( $this->use_verbose_page_rules ) {
-			$this->rules = array_merge( $this->extra_rules_top, $robots_rewrite, $deprecated_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $page_rewrite, $post_rewrite, $this->extra_rules );
+			$this->rules = array_merge( $this->extra_rules_top, $robots_rewrite, $favicon_rewrite, $deprecated_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $page_rewrite, $post_rewrite, $this->extra_rules );
 		} else {
-			$this->rules = array_merge( $this->extra_rules_top, $robots_rewrite, $deprecated_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $page_rewrite, $this->extra_rules );
+			$this->rules = array_merge( $this->extra_rules_top, $robots_rewrite, $favicon_rewrite, $deprecated_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $page_rewrite, $this->extra_rules );
 		}
 
 		/**
Index: src/wp-includes/class-wp.php
===================================================================
--- src/wp-includes/class-wp.php	(revision 45452)
+++ src/wp-includes/class-wp.php	(working copy)
@@ -14,7 +14,7 @@
 	 * @since 2.0.0
 	 * @var string[]
 	 */
-	public $public_query_vars = array( 'm', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'tag', 'feed', 'author_name', 'static', 'pagename', 'page_id', 'error', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'robots', 'taxonomy', 'term', 'cpage', 'post_type', 'embed' );
+	public $public_query_vars = array( 'm', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'tag', 'feed', 'author_name', 'static', 'pagename', 'page_id', 'error', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'robots', 'favicon', 'taxonomy', 'term', 'cpage', 'post_type', 'embed' );
 
 	/**
 	 * Private query variables.
@@ -662,8 +662,8 @@
 			return;
 		}
 
-		// Never 404 for the admin, robots, or if we found posts.
-		if ( is_admin() || is_robots() || $wp_query->posts ) {
+		// Never 404 for the admin, robots, favicon, or if we found posts.
+		if ( is_admin() || is_robots() || is_favicon() || $wp_query->posts ) {
 
 			$success = true;
 			if ( is_singular() ) {
Index: src/wp-includes/default-filters.php
===================================================================
--- src/wp-includes/default-filters.php	(revision 45452)
+++ src/wp-includes/default-filters.php	(working copy)
@@ -339,6 +339,7 @@
 add_action( 'do_feed_atom', 'do_feed_atom', 10, 1 );
 add_action( 'do_pings', 'do_all_pings', 10, 1 );
 add_action( 'do_robots', 'do_robots' );
+add_action( 'do_favicon', 'do_favicon' );
 add_action( 'set_comment_cookies', 'wp_set_comment_cookies', 10, 3 );
 add_action( 'sanitize_comment_cookies', 'sanitize_comment_cookies' );
 add_action( 'admin_print_scripts', 'print_emoji_detection_script' );
Index: src/wp-includes/functions.php
===================================================================
--- src/wp-includes/functions.php	(revision 45452)
+++ src/wp-includes/functions.php	(working copy)
@@ -1497,6 +1497,39 @@
 }
 
 /**
+ * Display the favicon.ico file content.
+ *
+ * @since 5.3.0
+ */
+function do_favicon() {
+	/**
+	 * Fires when serving the favicon.ico file.
+	 *
+	 * @since 5.3.0
+	 */
+	do_action( 'do_faviconico' );
+
+	if ( has_site_icon() ) {
+		$site_icon_id = get_option( 'site_icon' );
+		$site_icon    = wp_get_attachment_image_src( $site_icon_id, array( 32, 32 ) );
+		$site_icon    = $site_icon[0];
+	} else {
+		$site_icon = ABSPATH . 'wp-admin/images/w-logo-blue.png';
+	}
+
+	$filetype = wp_check_filetype( $site_icon );
+	if ( $filetype['type'] ) {
+		$mime_type = $filetype['type'];
+	} else {
+		$mime_type = 'image/x-icon';
+	}
+
+	header( "Content-Type: $mime_type" );
+	readfile( $site_icon );
+	exit;
+}
+
+/**
  * Determines whether WordPress is already installed.
  *
  * The cache will be checked first. If you have a cache plugin, which saves
Index: src/wp-includes/load.php
===================================================================
--- src/wp-includes/load.php	(revision 45452)
+++ src/wp-includes/load.php	(working copy)
@@ -162,6 +162,7 @@
  * Instead, send the headers for a zero-length favicon and bail.
  *
  * @since 3.0.0
+ * @deprecated 5.3.0 Deprecated in favor of do_favicon().
  */
 function wp_favicon_request() {
 	if ( '/favicon.ico' == $_SERVER['REQUEST_URI'] ) {
Index: src/wp-includes/query.php
===================================================================
--- src/wp-includes/query.php	(revision 45452)
+++ src/wp-includes/query.php	(working copy)
@@ -623,7 +623,7 @@
 }
 
 /**
- * Is the query for the robots file?
+ * Is the query for the robots.txt file?
  *
  * @since 2.1.0
  *
@@ -643,6 +643,26 @@
 }
 
 /**
+ * Is the query for the favicon.ico file?
+ *
+ * @since 5.3.0
+ *
+ * @global WP_Query $wp_query Global WP_Query instance.
+ *
+ * @return bool
+ */
+function is_favicon() {
+	global $wp_query;
+
+	if ( ! isset( $wp_query ) ) {
+		_doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1.0' );
+		return false;
+	}
+
+	return $wp_query->is_favicon();
+}
+
+/**
  * Determines whether the query is for a search.
  *
  * For more information on this and similar theme functions, check out
Index: src/wp-includes/template-loader.php
===================================================================
--- src/wp-includes/template-loader.php	(revision 45452)
+++ src/wp-includes/template-loader.php	(working copy)
@@ -36,6 +36,14 @@
 	 */
 	do_action( 'do_robots' );
 	return;
+elseif ( is_favicon() ) :
+	/**
+	 * Fired when the template loader determines a favicon.ico request.
+	 *
+	 * @since 5.3.0
+	 */
+	do_action( 'do_favicon' );
+	return;
 elseif ( is_feed() ) :
 	do_feed();
 	return;
Index: src/wp-settings.php
===================================================================
--- src/wp-settings.php	(revision 45452)
+++ src/wp-settings.php	(working copy)
@@ -67,9 +67,6 @@
 // Standardize $_SERVER variables across setups.
 wp_fix_server_vars();
 
-// Check if we have received a request due to missing favicon.ico
-wp_favicon_request();
-
 // Check if we're in maintenance mode.
 wp_maintenance();
 
